//=======================================================
//  Input LCD RGB Interface 
//=======================================================

module rgb_input(
	// RGB CLOCK //
	 input 		          		pclk
	// RGB CONTROL //
    ,input                      de
    ,input                      hs
    ,input                      vs
	// RGB DATA //
    ,input      [8 -1: 0]       pr
    ,input      [8 -1: 0]       pg
    ,input      [8 -1: 0]       pb
	// Internal CONTROL & RESET_n//
    ,input                      reset_n
    ,input      [11 -1: 0]      weight_in  //2047>1920
    ,input      [11 -1: 0]      height_in  //2047>1080
    ,input                      vs_polarity
    ,input                      hs_polarity
    // To rgb_output module
    ,output reg                 hs_switch_req
    ,input                      hs_switch_ack
    // RGB RAM Interface
    ,output reg                 rgb_write
    ,output reg [12 -1: 0]      rgb_waddr
    ,output reg [24 -1: 0]      rgb_wdata
    ,output wire                vs_ir_out
);

//=======================================================
//  Local parametr 
//=======================================================
localparam      RAM0_BASE = 0;
localparam      RAM1_BASE = 2048;

//=======================================================
//  REG/WIRE declarations
//=======================================================
reg                     hs_ir /* synthesis syn_useioff = 1*/;
reg                     vs_ir /* synthesis syn_useioff = 1*/;
reg                     de_ir /* synthesis syn_useioff = 1*/;
reg       [8 -1: 0]     pr_ir /* synthesis syn_useioff = 1*/;
reg       [8 -1: 0]     pg_ir /* synthesis syn_useioff = 1*/;
reg       [8 -1: 0]     pb_ir /* synthesis syn_useioff = 1*/;
reg                     vs_first_valid;
reg                     hs_reg;
reg                     vs_reg;
reg                     de_reg;
wire                    vs_posPulse;
wire                    vs_negPulse;
wire                    hs_posPulse;
wire                    hs_negPulse;
//! reg     [22 -1: 0]      pixel_count;
reg     [11 -1: 0]      linePix_addr;
reg     [11 -1: 0]      line_count; //2047
reg     [12 -1: 0]      base_addr; //4095

reg     [11 -1: 0]      weight;  //2047>1920
reg     [11 -1: 0]      height;  //2047>1080

//=======================================================
//  Structural coding
//=======================================================
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    vs_ir <= !vs_polarity;
    hs_ir <= !hs_polarity;
    de_ir <= 0;  
    pr_ir <= 0;
    pg_ir <= 0;
    pb_ir <= 0;

    vs_reg <= !vs_polarity;
    hs_reg <= !hs_polarity;
    de_reg <= 0;
  end else begin
    vs_ir <= vs;
    hs_ir <= hs;
    de_ir <= de;
    pr_ir <= pr;
    pg_ir <= pg;
    pb_ir <= pb;  
    vs_reg <= vs_ir;
    hs_reg <= hs_ir;
    de_reg <= de_ir;
  end
end
assign vs_posPulse = vs_ir & (!vs_reg);
assign vs_negPulse = (!vs_ir) & vs_reg;
assign hs_posPulse = hs_ir & (!hs_reg);
assign hs_negPulse = (!hs_ir) & hs_reg;
assign de_posPulse = de_ir & (!de_reg);
assign de_negPulse = (!de_ir) & de_reg;
assign vs_ir_out = vs_ir;

//--Indacate the valid vs at the first frame.
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    vs_first_valid <= 0;
  end else if(vs_negPulse) begin
    vs_first_valid <= 1;
  end else if(vs_posPulse) begin
    vs_first_valid <= 0;
  end
end

// register the frame height and weight at the vs_posPulse.
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    weight <= 0;
    height <= 0;
  end else if(vs_posPulse) begin
    weight <= weight_in;
    height <= height_in;
  end
end

//-- counter the input RGB data number
//! always @ (posedge pclk or negedge reset_n)
//! begin
//!   if(!reset_n) begin
//!     pixel_count <= 0;
//!   end else if (vs_posPulse) begin
//!     pixel_count <= 0;
//!   end else if (de) begin
//!     pixel_count <= pixel_count + 1'b1;
//!   end
//! end

always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    linePix_addr <= 0;
  end else if (vs_posPulse | hs_posPulse) begin
    linePix_addr <= 0;
  end else if (de_ir) begin
    linePix_addr <= linePix_addr + 1'b1;
  end
end

//-- counter the hs line number
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    line_count <= 0;
  end else if (vs_posPulse) begin
    line_count <= 0;
  end else if (de_negPulse) begin
    line_count <= line_count + 1'b1;
  end
end

//-- generete the base_addr
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    base_addr <= RAM0_BASE;
  end else if (line_count[0] == 1'b0) begin
    base_addr <= RAM0_BASE;
  end else if (line_count[0] == 1'b1) begin
    base_addr <= RAM1_BASE;
  end
end

//-- generate the rgb ram interface
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    rgb_write <= 0;
    rgb_waddr <= 0;
    rgb_wdata <= 0;
  end else if (de_ir) begin
    rgb_write <= 1;
    rgb_waddr <= {base_addr + linePix_addr};
    rgb_wdata <= {pr_ir, pg_ir, pb_ir};
  end else begin
    rgb_write <= 0;
    rgb_waddr <= 0;
    rgb_wdata <= 0;
  end
end

//-- generate the hs switch signals 
always @ (posedge pclk or negedge reset_n)
begin
  if (!reset_n) begin
    hs_switch_req <= 0;
  end else if (hs_switch_ack) begin
    hs_switch_req <= 0;
  end else if (de_negPulse && vs_first_valid) begin
    hs_switch_req <= 1;
  end
end


endmodule

